﻿/*
* This file is part of WinMergeFS.
*
* WinMergeFS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.

* WinMergeFS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WinMergeFS.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WinMergeFS.Common;
using System.Data;
using RealtimeTrace;

namespace WinMergeFS.API
{
    /// <summary>
    /// Provides save and load methods for profiles. Manages available profiles.
    /// </summary>
    public static class ProfileManager
    {

        public static List<Profile> AvailableProfiles
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        public static LoggerEventHandler _logger;

        /// <summary>
        /// Loads a profile from a filename.
        /// </summary>
        public static Profile LoadProfileFromFile(string Filename)
        {
            try
            {

                DataSet x = GetDataSet();

                if (!System.IO.File.Exists(Filename))
                {
                    _logger("ProfileManager: Cannot load profile: " + Filename + " doesn't exist.", LogLevel.error);
                    return null;
                }
                x.ReadXml(Filename);


                List<RootEntry> newroots = new List<RootEntry>();
                for (int i = 0; i < x.Tables["roots"].Rows.Count; i++)
                {
                    newroots.Add(new RootEntry((string)x.Tables["roots"].Rows[i]["path"], (bool)x.Tables["roots"].Rows[i]["readonly"]));
                }

                Dictionary<string, ProfilePluginEntry> newdict = new Dictionary<string, ProfilePluginEntry>();
                for (int i = 0; i < x.Tables["plugins"].Rows.Count; i++)
                {
                    newdict.Add(
                        (string)x.Tables["plugins"].Rows[i]["pluginid"],
                        new ProfilePluginEntry(
                            (string)x.Tables["plugins"].Rows[i]["pluginid"],
                            (int)x.Tables["plugins"].Rows[i]["position"],
                            (int)x.Tables["plugins"].Rows[i]["multiply"],
                            (int)x.Tables["plugins"].Rows[i]["parameter"]
                        )
                    );
                }

                return new Profile(
                    (string)x.Tables["general"].Rows[0]["description"],
                    (string)x.Tables["general"].Rows[0]["volumeid"],
                    (char)x.Tables["general"].Rows[0]["driveletter"],
                    newroots,
                    newdict
                );
            }
            catch (Exception ex)
            {
                _logger("ProfileManager: Could not load profile: Make sure the xml file is ok.",LogLevel.error);
                TraceFactory.InsertTrace(null, ex, Filename);
                return null;
            }
        }

        /// <summary>
        /// Saves a profile to a file.
        /// </summary>
        public static bool SaveProfileToFile(Profile Profile, string Filename)
        {
            try
            {
                DataSet x = GetDataSet();

                DataRow generalrow = x.Tables["general"].NewRow();
                generalrow["driveletter"] = Profile.DriveLetter;
                generalrow["description"] = Profile.Description;
                generalrow["volumeid"] = Profile.VolumeID;
                x.Tables["general"].Rows.Add(generalrow);

                for (int i = 0; i < Profile.Roots.Count; i++)
                {
                    DataRow rootrow = x.Tables["roots"].NewRow();
                    rootrow["path"] = Profile.Roots[i].RootPath;
                    rootrow["readonly"] = Profile.Roots[i].ReadOnly;
                    x.Tables["roots"].Rows.Add(rootrow);
                }

                foreach (ProfilePluginEntry entry in Profile.Plugins.Values)
                {
                    DataRow profilerow = x.Tables["plugins"].NewRow();
                    profilerow["pluginid"] = entry.PluginID;
                    profilerow["position"] = entry.Position;
                    profilerow["multiply"] = entry.Multiply;
                    profilerow["parameter"] = entry.Parameter;
                    x.Tables["plugins"].Rows.Add(profilerow);
                }

                x.WriteXml(Filename);
                return true;
            }
            catch (Exception ex)
            {
                _logger("ProfileManager: Could not save profile to file.",LogLevel.error);
                TraceFactory.InsertTrace(null, ex, Filename); return false;
            }

        }

        /// <summary>
        /// Creates a new profile.
        /// </summary>
        public static Profile NewProfile(string Description, string VolumeID, char DriveLetter, List<RootEntry> Roots, Dictionary<string, ProfilePluginEntry> Plugins)
        {
            try
            {
                Profile _profile = new Profile(Description, VolumeID, DriveLetter, Roots, Plugins);
                return _profile;
            }
            catch (Exception ex)
            { TraceFactory.InsertTrace(null, ex, Description, VolumeID, DriveLetter, Roots, Plugins); return null; }
        }

        /// <summary>
        /// Returns a DataSet of the profile structure
        /// </summary>
        private static DataSet GetDataSet()
        {
            try
            {
                DataSet x = new DataSet();
                x.Tables.Add("general");
                x.Tables["general"].Columns.Add("driveletter", System.Type.GetType("System.Char"));
                x.Tables["general"].Columns.Add("volumeid", System.Type.GetType("System.String"));
                x.Tables["general"].Columns.Add("description", System.Type.GetType("System.String"));

                x.Tables.Add("roots");
                x.Tables["roots"].Columns.Add("path", System.Type.GetType("System.String"));
                x.Tables["roots"].Columns.Add("readonly", System.Type.GetType("System.Boolean"));

                x.Tables.Add("plugins");
                x.Tables["plugins"].Columns.Add("pluginid", Type.GetType("System.String"));
                x.Tables["plugins"].Columns.Add("position", Type.GetType("System.Int32"));
                x.Tables["plugins"].Columns.Add("multiply", Type.GetType("System.Int32"));
                x.Tables["plugins"].Columns.Add("parameter", Type.GetType("System.Int32"));

                return x;

            }
            catch (Exception ex)
            { TraceFactory.InsertTrace(null, ex); throw; }

        }
    }
}
